﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UseCase.CopyPaste.cs" company="">
//   
// </copyright>
// <summary>
//   The use case.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Libium.UseCases
{
    using System;

    using Libium.Core;

    /// <summary>
    ///   The use case.
    /// </summary>
    public abstract partial class UseCase
    {
        #region Public Methods and Operators

        /// <summary>
        /// The finish copy.
        /// </summary>
        /// <param name="action">
        /// The action. 
        /// </param>
        /// <exception cref="InvalidOperationException">
        /// </exception>
        public void FinishCopy(CopyAction action)
        {
            var options = this.GetCopyOptions();
            if (!options.IsEnabled(action))
            {
                throw new InvalidOperationException();
            }

            this.DoFinishCopy(action);
        }

        /// <summary>
        ///   The get copy options.
        /// </summary>
        /// <returns> The <see cref="CopyOptions" /> . </returns>
        public CopyOptions GetCopyOptions()
        {
            var options = this.BuildCopyOptions();
            options.CanCopy &= this.Enabled;
            options.CanMove &= this.Enabled;
            options.CanMove &= !this.ReadOnly;
            options.CanLink &= this.Enabled;
            return options;
        }

        /// <summary>
        /// The get paste options.
        /// </summary>
        /// <param name="data">
        /// The data. 
        /// </param>
        /// <returns>
        /// The <see cref="PasteOptions"/> . 
        /// </returns>
        public PasteOptions GetPasteOptions(ICopyData data)
        {
            var options = this.BuildPasteOptions(data);
            var can = this.Enabled && !this.ReadOnly;
            options.CanCopy &= can;
            options.CanMove &= can;
            options.CanLink &= can;
            return options;
        }

        /// <summary>
        /// The paste.
        /// </summary>
        /// <param name="data">
        /// The data. 
        /// </param>
        /// <param name="action">
        /// The action. 
        /// </param>
        /// <exception cref="InvalidOperationException">
        /// </exception>
        public void Paste(ICopyData data, CopyAction action)
        {
            var options = this.GetPasteOptions(data);
            if (!options.IsEnabled(action))
            {
                throw new InvalidOperationException();
            }

            this.DoPaste(data, action);
        }

        /// <summary>
        ///   The start copy.
        /// </summary>
        /// <returns> The <see cref="ICopyData" /> . </returns>
        /// <exception cref="InvalidOperationException"></exception>
        public ICopyData StartCopy()
        {
            var options = this.GetCopyOptions();
            if (!(options.CanCopy || options.CanMove || options.CanLink))
            {
                throw new InvalidOperationException();
            }

            return this.DoStartCopy();
        }

        #endregion

        #region Methods

        /// <summary>
        ///   The build copy options.
        /// </summary>
        /// <returns> The <see cref="CopyOptions" /> . </returns>
        protected virtual CopyOptions BuildCopyOptions()
        {
            return new CopyOptions { CanCopy = false, CanMove = false, CanLink = false };
        }

        /// <summary>
        /// The build paste options.
        /// </summary>
        /// <param name="data">
        /// The data. 
        /// </param>
        /// <returns>
        /// The <see cref="PasteOptions"/> . 
        /// </returns>
        protected virtual PasteOptions BuildPasteOptions(ICopyData data)
        {
            return new PasteOptions
                {
                   CanCopy = false, CanMove = false, CanLink = false, DefaultAction = CopyAction.Copy 
                };
        }

        /// <summary>
        /// The do finish copy.
        /// </summary>
        /// <param name="action">
        /// The action. 
        /// </param>
        protected virtual void DoFinishCopy(CopyAction action)
        {
            if (action == CopyAction.Move)
            {
                this.Parent.DeleteUseCase(this);
            }
        }

        /// <summary>
        /// The do paste.
        /// </summary>
        /// <param name="data">
        /// The data. 
        /// </param>
        /// <param name="action">
        /// The action. 
        /// </param>
        protected virtual void DoPaste(ICopyData data, CopyAction action)
        {
            this.ErrorWithOk("Pasted data is empty or in unsupported format");
        }

        /// <summary>
        ///   The do start copy.
        /// </summary>
        /// <returns> The <see cref="ICopyData" /> . </returns>
        protected virtual ICopyData DoStartCopy()
        {
            return new CopyData();
        }

        /// <summary>
        /// The on copy command.
        /// </summary>
        /// <param name="call">
        /// The call. 
        /// </param>
        protected virtual void OnCopyCommand(CommandCall call)
        {
        }

        /// <summary>
        /// The on cut command.
        /// </summary>
        /// <param name="call">
        /// The call. 
        /// </param>
        protected virtual void OnCutCommand(CommandCall call)
        {
        }

        /// <summary>
        /// The on paste command.
        /// </summary>
        /// <param name="call">
        /// The call. 
        /// </param>
        protected virtual void OnPasteCommand(CommandCall call)
        {
            // var dataObject = Clipboard.GetDataObject();
            // if (dataObject == null) return;

            // var formats = dataObject.GetFormats();
            // var supportedFormats = GetSupportedPasteFormats();
            // if (supportedFormats == null) return;

            // foreach (var supportedFormat in supportedFormats)
            // {
            // 	if (formats.Contains(supportedFormat))
            // 	{
            // 		Paste(supportedFormat, dataObject.GetData(supportedFormat));
            // 	}
            // }
        }

        #endregion
    }
}